package org.mashibing.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import org.mashibing.constant.CommonStatusEnum;
import org.mashibing.constant.TokenTypeConstant;
import org.mashibing.dto.ResponseResult;
import org.mashibing.dto.TokenResult;
import org.mashibing.response.TokenResponse;
import org.mashibing.service.TokenService;
import org.mashibing.util.JwtUtils;
import org.mashibing.util.RedisPrefixUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author:
 * @create: 2024/4/1 15:13
 * @description:
 */
@Service
public class TokenServiceImpl implements TokenService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ResponseResult<TokenResponse> refreshToken(String refreshToken) {
        // 解析refreshToken
        TokenResult tokenResult = JwtUtils.pareToken(refreshToken);
        String phone = tokenResult.getPhone();
        String identity = tokenResult.getIdentity();

        // 读取redis中的refreshToken
        String tokenKey = RedisPrefixUtil.generatorTokenKey(phone, identity, TokenTypeConstant.REFRESH_TOKEN_TYPE);
        String redisRefreshToken = stringRedisTemplate.opsForValue().get(tokenKey);

        // 校验refreshToken
        if (StringUtils.isBlank(tokenKey) || !Objects.equals(refreshToken, redisRefreshToken)) {
            return ResponseResult.fail(CommonStatusEnum.TOKEN_ERROR.getCode(),CommonStatusEnum.TOKEN_ERROR.getValue());
        }

        // 重新生成accessToken和refreshToken
        String accessTokenNew = JwtUtils.generatorToken(phone, identity, TokenTypeConstant.ACCESS_TOKEN_TYPE);
        String refreshTokenNew = JwtUtils.generatorToken(phone, identity, TokenTypeConstant.REFRESH_TOKEN_TYPE);

        // 存入redis
        String accessTokenKeyNew = RedisPrefixUtil.generatorTokenKey(phone, identity, TokenTypeConstant.ACCESS_TOKEN_TYPE);
        stringRedisTemplate.opsForValue().set(accessTokenKeyNew, accessTokenNew, 30, TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(tokenKey, refreshTokenNew, 31, TimeUnit.DAYS);

        TokenResponse tokenResponse = new TokenResponse(accessTokenNew, refreshTokenNew);
        return ResponseResult.success(tokenResponse);
    }
}
